{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Neural physical engines for inferring the halo mass distribution function\n",
    "\n",
    "Tom Charnock\n",
    "\n",
    "Institut d'Astrophysique de Paris\n",
    "<br><br><br>\n",
    "Notebook: <a href=\"http://presentations.charnock.fr/NPE/Neural%20physical%20engines%20for%20inferring%20the%20halo%20mass%20distribution%20function.ipynb\" download>presentations.charnock.fr/NPE</a>\n",
    "\n",
    "<table style=\"width:100%;\" border=\"0\">\n",
    "    <tr style=\"background-color:white;\"><td>\n",
    "        <img src=\"../figures/SU.png\" alt=\"Sorbonne Université\" style=\"height: 80px;\"/>\n",
    "    </td><td>\n",
    "        <img src=\"../figures/ANR.png\" alt=\"ANR\" style=\"height: 100px;\"/>\n",
    "    </td><td>\n",
    "        <img src=\"../figures/IAP.png\" alt=\"IAP\" style=\"height: 100px;\"/>\n",
    "    </td><td>\n",
    "        <img src=\"../figures/CNRS.png\" alt=\"CNRS\" style=\"height: 100px;\"/>\n",
    "    </td><td>\n",
    "        <img src=\"../figures/Aquila.png\" alt=\"Aquila\" style=\"height: 100px;\"/>\n",
    "    </td></tr>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Cosmology from the universe\n",
    "<img style=\"max-width:100%;max-height:60%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/cosmology.svg\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "#### Bayesian Origins Reconstruction of Galaxies (BORG)\n",
    "\n",
    "<img style=\"max-width:90%;max-height:60%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/BORG.svg\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "#### Infer the dark matter field from any catalogue\n",
    "\n",
    "<img style=\"max-width:100%;max-height:60%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/Aquila.png\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Halo mass distribution function"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "<img style=\"max-width:100%;max-height:60%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/DM.jpg\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Distribution of halos\n",
    "- Press Schechter (gravitational collapse following power law at small masses, exponential cut-off)\n",
    "- Local density deviations\n",
    "- Unknown stochasticity (Poissionian)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Halo mass distribution\n",
    "<img style=\"width:800px;max-height:100%;display:block;margin:auto;float:none!important;\" src=\"../figures/hmd.svg\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Neural bias model\n",
    "<br><br><br><br><br><br><br>\n",
    "<sub><a href=\"https://github.com/tomcharnock/neural_bias_model\">github:neural_bias_model</a></sub>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Neural physical engines\n",
    "\n",
    "Build networks using physical principles.\n",
    "\n",
    "- Reduces number of parameters\n",
    "\n",
    "- Increases computational efficiency\n",
    "\n",
    "- Decreases overfitting\n",
    "\n",
    "- Improves interpretability"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Convolutions for translational invariance\n",
    "<img style=\"max-width:80%;max-height:60%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/convolutional_network.svg\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Architecture suited to the data\n",
    "\n",
    "<img style=\"max-width:80%;max-height:60%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/spherical_convolutional_network.svg\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Use only causally relevant features\n",
    "<img style=\"max-width:90%;max-height:60%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/receptive_field.svg\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Use only informative features\n",
    "<br>\n",
    "<img style=\"max-width:80%;max-height:60%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/kernels.svg\">\n",
    "<br>\n",
    "<sub><a href=\"https://github.com/tomcharnock/multipole_kernels\">github:multipole_kernels</a></sub>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# What's the best map from the dark matter density today to some summary of the halos?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### We don't actually know yet..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "#### We do know that it should be:\n",
    "- Dependent on the local patch\n",
    "- Mostly sensitive to the amplitude\n",
    "- Independent of position on the sky"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Our neural physical engine\n",
    "<br>\n",
    "<img style=\"max-width:80%;max-height:60%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/NPE.svg\">\n",
    "<br>\n",
    "$${\\Tiny \\psi_j^{\\ell,m} = A\\left(\\sum_{i=-\\kappa/2}^{i=\\kappa/2}K_{i}^{\\ell,m}\\delta_{j-i}^\\textrm{LPT}+b_j\\right), ~~~ \\ell=0, m=0}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Neural density estimators"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "#### Halo mass distribution function is a smooth function of mass given a density environment"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "# Use a mixture density network"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "<img style=\"max-width:90%;max-height:70%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/MDN.svg\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Our neural density estimator\n",
    "$$\\begin{align*}\n",
    "        {\\tiny n(M|\\delta) =}&{\\tiny \\sum_i^N\\alpha(\\boldsymbol{\\psi}, \\boldsymbol{\\theta}_i^{\\boldsymbol{\\alpha}})\\mathcal{N}\\left(\\mu(\\boldsymbol{\\psi}, \\boldsymbol{\\theta}_i^{\\boldsymbol{\\mu}}), \\sigma(\\boldsymbol{\\psi}, \\boldsymbol{\\theta}_i^{\\boldsymbol{\\sigma}})|M\\right),}\\\\\n",
    "        {\\tiny =}&{\\tiny \\sum_i^N\\frac{\\alpha(\\boldsymbol{\\psi}, \\boldsymbol{\\theta}_i^{\\boldsymbol{\\alpha}})}{\\sqrt{2\\pi\\left(\\sigma(\\boldsymbol{\\psi}, \\boldsymbol{\\theta}_i^{\\boldsymbol{\\sigma}})\\right)^2}}\\exp\\left[-\\frac{\\left(\\log(M) - \\mu(\\boldsymbol{\\psi}, \\boldsymbol{\\theta}_i^{\\boldsymbol{\\mu}})\\right)^2}{2\\left(\\sigma(\\boldsymbol{\\psi}, \\boldsymbol{\\theta}_i^{\\boldsymbol{\\sigma}})\\right)^2}\\right],}\\end{align*}\n",
    "$$\n",
    "<div style=\"float:left;width:40%\">\n",
    "    <img style=\"max-width:100%;max-height:70%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/MOG.svg\">\n",
    "</div>\n",
    "<div style=\"float:right;width:59%\">\n",
    "    $$\n",
    "    \\begin{align*}\n",
    "{\\tiny\\alpha_i} & {\\tiny=\\text{softplus}(w_{i}^\\alpha\\boldsymbol{\\psi}+b^\\alpha_i),}\\\\\n",
    "{\\tiny\\mu_i }&{\\tiny = \\left\\{\\begin{array}{ll}\n",
    "            w_{i}^\\mu\\boldsymbol{\\psi}+b^\\mu_i&i=0\\\\\n",
    "            \\textrm{Max}\\left[0,~ w_{i}^\\mu\\boldsymbol{\\psi}+b^\\mu_i\\right]+\\mu_{i-1}&i>0\\\\\n",
    "            \\end{array}\\right.,}\\\\\n",
    "{\\tiny\\sigma_i} &{\\tiny = \\text{softplus}(w_{i}^\\sigma\\boldsymbol{\\psi}+b^\\sigma_i)\\;,}\n",
    "    \\end{align*}\n",
    "    $$\n",
    "</div>\n",
    "<div style=\"float:left;width:100%\">\n",
    "<sub>2 Gaussians with<br> ${\\Tiny\\boldsymbol{b}^\\alpha \\to \\boldsymbol{b}^\\alpha +\\log(10^{-3})}$, ${\\Tiny b_0^\\mu \\to b_0^\\mu + \\log\\left(2\\times10^{12}\\right)}$ and ${\\Tiny\\boldsymbol{b}^\\sigma\\to \\boldsymbol{b}^\\alpha + \\log(10^3)}$.</sub>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Likelihood"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "$$\\begin{align*}\n",
    "        {\\Tiny\\mathcal{L}  =}&{\\Tiny \\sum_{j\\in\\textrm{catalogue}}\\log\\left[\\sum_i^N\\frac{\\alpha_{i,j}}{\\sqrt{2\\pi\\sigma_{i,j}^2}}\\exp\\left[-\\frac{\\left(\\log(M_j) - \\mu_{i,j}\\right)^2}{2\\sigma_{i,j}^2}\\right]\\right]}\\\\\n",
    "        &{\\Tiny - V\\sum_{j\\in\\textrm{voxels},i=1}^N\\frac{\\alpha_{i,j}}{2}\\exp\\left[\\frac{\\sigma_{i,j}^2}{2}\\right]\\textrm{erfc}\\left[\\frac{\\log\\left(M_\\textrm{th}\\right) - \\mu_{i,j} - \\sigma_{i,j}^2}{\\sqrt{2\\sigma_{i,j}^2}}\\right].}\n",
    "    \\end{align*}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "This is Poissonian.<br>\n",
    "But on the NPE field, so it is non-local"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# HMCLET"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### We want to infer the weights of the neural bias model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Hamiltonian Monte Carlo\n",
    "<div style=\"float:left;width:60%\">\n",
    "<sub>Introduce momentum ${\\small {\\bf p}\\leftarrow\\mathcal{N}({\\bf 0},{\\bf M})}$ and solve Hamilton's equations</sub>\n",
    "<br><br>\n",
    "$$\\begin{align*}\n",
    "{\\Tiny\\mathcal{H}(\\boldsymbol{\\theta}, {\\bf p}) }&{\\Tiny~= \\mathcal{V}(\\boldsymbol{\\theta}) + \\mathcal{K}({\\bf p})}\\\\\n",
    "&{\\Tiny~=\\mathcal{L}(\\boldsymbol{\\theta}|\\boldsymbol{\\delta})-\\log\\left[\\pi(\\boldsymbol{\\theta})\\right]+\\frac{1}{2}{\\bf p}^T{\\bf M}^{-1}{\\bf p}}\n",
    "\\end{align*}$$\n",
    "<sub>Accept samples according to probability</sub>\n",
    "\n",
    "$$\\begin{equation*}\n",
    "    {\\Tiny\\alpha = \\textrm{Min}\\left[\\exp\\left(\\Delta\\mathcal{H}\\right), 1\\right]}\n",
    "\\end{equation*}$$\n",
    "</div>\n",
    "<div style=\"float:right;width:35%\">\n",
    "    <br><br>\n",
    "    <img style=\"max-width:100%;max-height:70%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/HMC_theta.svg\">\n",
    "    <br>\n",
    "</div>\n",
    "<div style=\"float:left;width:100%\">\n",
    "Evolve using ${\\Tiny\\dot{\\boldsymbol{\\theta}}= {\\bf M}^{-1}{\\bf p}}$ and ${\\Tiny\\dot{\\bf p}= -\\nabla\\mathcal{V}(\\boldsymbol{\\theta})}$\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Acceptance is guaranteed if ODEs are perfectly solved"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "# Use leapfrog algorithm"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Leapfrog algorithm\n",
    "\n",
    "<img style=\"max-width:60%;max-height:70%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/leapfrog.svg\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Acceptance criterion\n",
    "\n",
    "<img style=\"max-width:60%;max-height:70%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/leapfrog_accept.svg\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# How does this work for neural networks?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Likelihood surface is extremely flat and highly degenerate\n",
    "<br>\n",
    "<img style=\"max-width:70%;max-height:70%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/correlated_likelihood.svg\">\n",
    "\n",
    "Nearly impossible to know the mass matrix, ${\\bf M}$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Use second order geometric information\n",
    "<img style=\"max-width:90%;max-height:70%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/second_order.svg\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Quasi-Newtonian inverse Hessian\n",
    "\n",
    "$$\\begin{equation*}\n",
    "        {\\Tiny{\\bf B}^*=\\left(\\mathbb{I}-\\frac{\\boldsymbol{s}_i\\boldsymbol{y}_i^T}{\\boldsymbol{y}_i^T\\boldsymbol{s}_i}\\right){\\bf B}_i\\left(\\mathbb{I}-\\frac{\\boldsymbol{y}_i\\boldsymbol{s}_i^T}{\\boldsymbol{y}_i^T\\boldsymbol{s}_i}\\right)+\\frac{\\boldsymbol{s}_i\\boldsymbol{s}_i^T}{\\boldsymbol{s}_i^T\\boldsymbol{y}_i},}\n",
    "    \\end{equation*}\n",
    "$$\n",
    "<sub>with ${\\Tiny\\boldsymbol{s}_i=\\boldsymbol{\\theta}^*-\\boldsymbol{\\theta}_i}$ and ${\\Tiny\\boldsymbol{y}_i=\\nabla\\mathcal{L}(\\boldsymbol{\\theta}^*|\\boldsymbol{\\delta})-\\nabla\\mathcal{L}(\\boldsymbol{\\theta}_i|\\boldsymbol{\\delta})}$.</sub>\n",
    "\n",
    "#### Both $\\boldsymbol{s}$ and $\\boldsymbol{y}$ come for free with the leapfrog algorithm"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## We can now successfully traverse the likelihood surface\n",
    "\n",
    "The momenta and trajectories get rescaled by the Hessian providing a surface which is not as highly degenerate or flat"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Actual results"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## VELMASS simulation\n",
    "\n",
    "- 125h<sup>-1</sup>Mpc chunk from 2h<sup>-1</sup>Gpc length box<br>\n",
    "- Rebinned to 64<sup>3</sup> voxels<br>\n",
    "- Planck-like cosmology<br>\n",
    "- Halos found using Rockstar ~ O(10<sup>4</sup>) halos\n",
    "- Minimum halo size of 8x10<sup>8</sup> solar masses"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Run BORG"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "\n",
    "<img style=\"max-width:100%;max-height:60%;display:block;height:auto;margin:auto;float:none!important;\" src=\"../figures/BORG.svg\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Sample the power spectrum\n",
    "<br>\n",
    "<img style=\"width:600px;max-width:200%;max-height:200%;display:block;margin:auto;float:none!important;\" src=\"../figures/Pk.svg\">\n",
    "✓ Power spectra remain smooth and close to prior"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "#### Sample the weights of the neural bias model\n",
    "<br>\n",
    "<img style=\"width:900px;max-width:100%;max-height:100%;display:block;margin:auto;float:none!important;\" src=\"../figures/weight_trace.svg\">\n",
    "\n",
    "✓ Weight values are properly sampled after burn in<br>\n",
    "✓ NPE acts as a contrast enhancer"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### See the effects of the neural physical engine\n",
    "<br>\n",
    "<img style=\"width:500px;max-height:100%;display:block;margin:auto;float:none!important;\" src=\"../figures/3D_projections.svg\">\n",
    "\n",
    "✓ Non-local information is used to improve fit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# And what does the halo mass distribution function look like?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "#### Halo mass distribution function from neural bias model\n",
    "<br>\n",
    "<img style=\"width:800px;max-height:100%;display:block;margin:auto;float:none!important;\" src=\"../figures/hmdf.svg\">\n",
    "✓ Fits data!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Conclusions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### First example of zero-shot training, fully Bayesian neural network"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- Using neural physical engines to keep number of parameters small\n",
    "- Using the HMCLET to sample the weights of the neural network even though the likelihood is flat and degenerate\n",
    "- Using BORG to infer the simulations"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Future work\n",
    "- Skip the bias completely by flowing the dark matter distribution to the stochastically sampled data (inferring the likelihood)\n",
    "- Optimisation of the neural physical engine architecture for optimal halo mass distribution function"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Neural physical engines for inferring the halo mass distribution function\n",
    "\n",
    "Tom Charnock\n",
    "\n",
    "Institut d'Astrophysique de Paris\n",
    "<br><br><br>\n",
    "\n",
    "\n",
    "<table style=\"width:100%;\" border=\"0\">\n",
    "    <tr style=\"background-color:white;\"><td>\n",
    "        <img src=\"../figures/SU.png\" alt=\"Sorbonne Université\" style=\"height: 80px;\"/>\n",
    "    </td><td>\n",
    "        <img src=\"../figures/ANR.png\" alt=\"ANR\" style=\"height: 100px;\"/>\n",
    "    </td><td>\n",
    "        <img src=\"../figures/IAP.png\" alt=\"IAP\" style=\"height: 100px;\"/>\n",
    "    </td><td>\n",
    "        <img src=\"../figures/CNRS.png\" alt=\"CNRS\" style=\"height: 100px;\"/>\n",
    "    </td><td>\n",
    "        <img src=\"../figures/Aquila.png\" alt=\"Aquila\" style=\"height: 100px;\"/>\n",
    "    </td></tr>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Diaporama",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
